package my.graduation.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import my.graduation.constant.ExamRecordStatusConstant;
import my.graduation.constant.RegRecordStatusConstant;
import my.graduation.dto.QueueDto;
import my.graduation.dto.DataDto;
import my.graduation.dto.RegRecordDto;
import my.graduation.entity.Clinic;
import my.graduation.entity.ExaminationRecord;
import my.graduation.entity.Patient;
import my.graduation.entity.RegistrationRecord;
import my.graduation.enums.HttpCodeEnums;
import my.graduation.mapper.ClinicMapper;
import my.graduation.mapper.DoctorMapper;
import my.graduation.mapper.PatientMapper;
import my.graduation.mapper.RegistrationRecordMapper;
import my.graduation.result.Result;
import my.graduation.service.RegistrationRecordService;
import my.graduation.util.RegQueueManager;
import my.graduation.vo.AlertPaidVO;
import my.graduation.vo.DataVO;
import my.graduation.vo.RegistrationRecordVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.stream.Collectors;

/**
 * @Author: RavenLyn
 * @Date: 2024-12-20
 */
@Service
public class RegistrationRecordServiceImpl extends ServiceImpl<RegistrationRecordMapper, RegistrationRecord> implements RegistrationRecordService {

    @Autowired
    private RegistrationRecordMapper registrationRecordMapper;

    /**
     * 订单支付成功，更新 status = 1 payTime
     * @param orderId
     * @param status
     * @return
     */
    @Override
    public Boolean paySuccess(Integer orderId, Integer status, Timestamp payTime) {
        return registrationRecordMapper.paySuccess(orderId,status,payTime);
    }

    /**
     * 退款 更新 status = 3
     * @param orderId
     * @param status
     * @return
     */
    public Boolean updateStatus(Integer orderId, Integer status) {
        return registrationRecordMapper.updateStatus(orderId,status);
    }

    /**
     * 使用orderId和patientId查询支付成功后的订单
     * @param dto
     * @return
     */
    @Override
    public Result<RegistrationRecord> getRegCurrentRecord(RegRecordDto dto) {
        // orderId  patientId
        if (dto.getOrderId() != null && dto.getPatientId() != null) {
            RegistrationRecord one = getOne(Wrappers.<RegistrationRecord>lambdaQuery()
                    .eq(RegistrationRecord::getOrderId, dto.getOrderId())
                    .eq(RegistrationRecord::getPatientId, dto.getPatientId()));

            if(one != null){
                System.out.println(one.getPayTime());
                return Result.success(one);
            }else {
                return Result.error(HttpCodeEnums.DATA_NOT_EXIST);
            }
        } else {
            return Result.error(HttpCodeEnums.DATA_NOT_EXIST);
        }
    }

    /**
     * 获取该patientId下的所有挂号记录
     * @param dto
     * @return
     */
    @Override
    public Result<List<RegistrationRecord>> getListByPatientId(RegRecordDto dto) {
        if(dto.getPatientId() != null){
            return  Result.success(list(Wrappers.<RegistrationRecord>lambdaQuery()
                    .eq(RegistrationRecord::getPatientId, dto.getPatientId())));
        }else {
            return Result.error(HttpCodeEnums.SYSTEM_ERROR);
        }
    }



//    /**
//     * 获取该patientId获取最近的挂号状态 -日期最大，且待就诊
//     * 主要返回clinicName
//     * @param dto
//     * @return
//     */
//    @Override
//    public Result<Clinic> getRegStatusByPatientId(RegRecordDto dto) {
//        if(dto.getPatientId() != null){
//            //1 查出该record的clinicId
//            RegistrationRecord one = getOne(Wrappers.<RegistrationRecord>lambdaQuery()
//                    .eq(RegistrationRecord::getPatientId, dto.getPatientId())
//                    .eq(RegistrationRecord::getStatus,RegRecordStatusConstant.PAID)
//                    .eq(RegistrationRecord::getDate,LocalDate.now()));
//            //2 用该clinicId去clinic表中查clinicName
////            System.out.println(one.getDate());
//            if(one == null){
//                return Result.error(HttpCodeEnums.DATA_NOT_EXIST);
//            }
//            Clinic clinic = clinicMapper.selectOne(Wrappers.<Clinic>lambdaQuery()
//                    .eq(Clinic::getId, one.getClinicId()));
////            String clinicName = clinic.getName();
////            System.out.println(clinicName);
//            return Result.success(clinic);
//        }else {
//            return Result.error(HttpCodeEnums.DATA_NOT_EXIST);
//        }
//
//    }

    @Autowired
    private PatientMapper patientMapper;

    /**
     * 医生获取当天当班次挂号列表
     * @param dto
     * @return
     */
    @Override
    public Result<List<RegistrationRecordVO>> getListByDoctorId(RegRecordDto dto) {
        if (dto.getDoctorId() != null && dto.getCurrentShift() != null) {
            LocalDate today = LocalDate.now();
            // 1 获取医生当天的挂号队列
            List<RegistrationRecord> list = new ArrayList<>();
            if(dto.getCurrentShift() == 0){ //上午班 获取timeSlot小于6的record
                list = list(Wrappers.<RegistrationRecord>lambdaQuery()
                        .eq(RegistrationRecord::getDoctorId, dto.getDoctorId())
                        .eq(RegistrationRecord::getDate, today)
                        // 使用.or连接多个条件
                        .or(wrapper -> wrapper
                                .eq(RegistrationRecord::getStatus, RegRecordStatusConstant.PAID)
                                .eq(RegistrationRecord::getStatus, RegRecordStatusConstant.FINISHED))
                        .lt(RegistrationRecord::getTimeSlot,6)
                        .orderByAsc(RegistrationRecord::getTimeSlot));
            }
            if(dto.getCurrentShift() == 1){ //下午班 获取timeSlot大于等于6的record
                list = list(Wrappers.<RegistrationRecord>lambdaQuery()
                        .eq(RegistrationRecord::getDoctorId, dto.getDoctorId())
                        .eq(RegistrationRecord::getDate, today)
                        // 使用.or连接多个条件
                        .or(wrapper -> wrapper
                                .eq(RegistrationRecord::getStatus, RegRecordStatusConstant.PAID)
                                .eq(RegistrationRecord::getStatus, RegRecordStatusConstant.FINISHED))
                        .ge(RegistrationRecord::getTimeSlot,6)
                        .orderByAsc(RegistrationRecord::getTimeSlot));
            }
            // 2 将list中的patientId获取出组成patientIdList
            List<Integer> patientIdList = list.stream()
                    .map(RegistrationRecord::getPatientId).collect(Collectors.toList());

            // 3 查询出patientList
            List<Patient> patientList = patientMapper.selectBatchIds(patientIdList);

            // 4 将 patientList 中的 id 和 name 封装成map,提高查询性能
            Map<Integer,String> map = patientList.stream()
                    .collect(Collectors.toMap(Patient::getId,Patient::getName));

            // 5 封装成voList
            List<RegistrationRecordVO> voList = new ArrayList<>();
            for(RegistrationRecord one : list){
                String patientName = map.get(one.getPatientId());
                RegistrationRecordVO newOne = new RegistrationRecordVO();
                BeanUtils.copyProperties(one,newOne);
                newOne.setPatientName(patientName);
                voList.add(newOne);
            }
            return Result.success(voList);
        } else {
            return Result.error(HttpCodeEnums.SYSTEM_ERROR);
        }
    }

    @Override
    public Result inquiryFinished(RegRecordDto dto) { // 传来 id
        if(dto.getId() != null){
            boolean i = update(Wrappers.<RegistrationRecord>lambdaUpdate()
                    .eq(RegistrationRecord::getId, dto.getId())
                    .set(RegistrationRecord::getStatus, RegRecordStatusConstant.FINISHED));
            if (i){
                return Result.success();
            }else {
                return Result.error(HttpCodeEnums.SYSTEM_ERROR);
            }
        }else {
            return Result.error(HttpCodeEnums.INFO_IS_BLANK);
        }
    }

    /**
     * 医生获取当天当前班次的挂号队列
     *
     * @param dto
     * @return
     */
    @Override
    public Result<List<Queue<RegistrationRecordVO>>> getQueues(QueueDto dto) {
        LocalDate today = LocalDate.now();
        // 前端点击开始叫号，传来doctorId和currentShift
        if(dto.getDoctorId() != null && dto.getCurrentShift() != null){
            //初始化队列
            RegQueueManager queueManager = new RegQueueManager(dto.getCurrentShift());

            List<RegistrationRecord> list = new ArrayList<>();
            if(dto.getCurrentShift() == 0){ //上午班 获取timeSlot小于6的record
                list = list(Wrappers.<RegistrationRecord>lambdaQuery()
                        .eq(RegistrationRecord::getDoctorId, dto.getDoctorId())
                        .eq(RegistrationRecord::getDate, today)
                        // 使用.or连接多个条件
                        .eq(RegistrationRecord::getStatus, RegRecordStatusConstant.PAID)
                        .or()
                        .eq(RegistrationRecord::getStatus, RegRecordStatusConstant.FINISHED)
                        .lt(RegistrationRecord::getTimeSlot,6)
                        .orderByAsc(RegistrationRecord::getTimeSlot));
            }
            if(dto.getCurrentShift() == 1){ //下午班 获取timeSlot大于等于6的record
                list = list(Wrappers.<RegistrationRecord>lambdaQuery()
                        .eq(RegistrationRecord::getDoctorId, dto.getDoctorId())
                        .eq(RegistrationRecord::getDate, today)
                        // 使用.or连接多个条件
                        .and(wrapper -> wrapper
                                .eq(RegistrationRecord::getStatus, RegRecordStatusConstant.PAID)
                                .or()
                                .eq(RegistrationRecord::getStatus, RegRecordStatusConstant.FINISHED))
                        .ge(RegistrationRecord::getTimeSlot,6)
                        .orderByAsc(RegistrationRecord::getTimeSlot));
            }
            // 2 将list中的patientId获取出组成patientIdList
            List<Integer> patientIdList = list.stream()
                    .map(RegistrationRecord::getPatientId).collect(Collectors.toList());

            if(patientIdList.isEmpty()){
                return Result.success();
            }

            // 3 查询出patientList
            List<Patient> patientList = patientMapper.selectBatchIds(patientIdList);

            // 4 将 patientList 中的 id 和 name 封装成map,提高查询性能
            Map<Integer,String> map = patientList.stream()
                    .collect(Collectors.toMap(Patient::getId,Patient::getName));

            // 5 封装成voList
            List<RegistrationRecordVO> voList = new ArrayList<>();
            for(RegistrationRecord record : list){
                String patientName = map.get(record.getPatientId());
                RegistrationRecordVO newOne = new RegistrationRecordVO();
                BeanUtils.copyProperties(record,newOne);
                newOne.setPatientName(patientName);
                voList.add(newOne);
            }

            // 6 封装成queue
            for(RegistrationRecordVO voRecord : voList){
                queueManager.addRecordToNormalQueue(voRecord.getTimeSlot(), voRecord);
            }

            return Result.success(queueManager.getNormalQueues());
        }else {
            return Result.error(HttpCodeEnums.SYSTEM_ERROR);
        }
    }

    @Autowired
    private ClinicMapper clinicMapper;

    /**
     * 管理员获取挂号数据 - 数据分析
     * @param dto
     * @return
     */
    @Override
    public Result<List<DataVO>> getRegData(DataDto dto) {
        if(dto.getClinicIdList() != null){
            List<RegistrationRecord> list = registrationRecordMapper.getListByClinicIdList(dto.getClinicIdList());
            List<DataVO> voList = new ArrayList<>();
            for(RegistrationRecord record : list){
                Clinic clinic = clinicMapper.selectById(record.getClinicId());
                DataVO newOne = new DataVO();
                newOne.setId(record.getId());
                newOne.setClinicName(clinic.getName());
                newOne.setClinicId(record.getClinicId());
                newOne.setDate(record.getDate());
                voList.add(newOne);
            }
            return Result.success(voList);
        }else {
            return Result.error(HttpCodeEnums.DATA_NOT_EXIST);
        }
    }

    /**
     * 管理员获取未就诊挂号记录
     * @return
     */
    @Override
    public Result<List<AlertPaidVO>> getPaidData() {
        List<RegistrationRecord> list = list(Wrappers.<RegistrationRecord>lambdaQuery()
                .eq(RegistrationRecord::getStatus, RegRecordStatusConstant.PAID));
        List<AlertPaidVO> voList = new ArrayList<>();
        for(RegistrationRecord record : list){
            Patient patient = patientMapper.selectById(record.getPatientId());
            Clinic clinic = clinicMapper.selectById(record.getClinicId());
            AlertPaidVO alertPaidVO = new AlertPaidVO();
            BeanUtils.copyProperties(record,alertPaidVO);
            alertPaidVO.setPhone(patient.getPhone());
            alertPaidVO.setName(patient.getName());
            alertPaidVO.setClinicName(clinic.getName());
            voList.add(alertPaidVO);
        }
        return Result.success(voList);
    }

    /**
     * 自动处理患者过期挂号预约
     */
    @Override
    public void handleExpired() {
        update(Wrappers.<RegistrationRecord>lambdaUpdate()
                .lt(RegistrationRecord::getDate, LocalDate.now())
                .set(RegistrationRecord::getStatus, ExamRecordStatusConstant.CANCELED));
    }
}
